package com.hghivln.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hghivln.constants.Constants;
import com.hghivln.mapper.*;
import com.hghivln.pojo.domain.*;
import com.hghivln.pojo.dto.*;
import com.hghivln.pojo.vo.AjaxResult;
import com.hghivln.service.RegistrationService;
import com.hghivln.utils.AppMd5Utils;
import com.hghivln.utils.IdGeneratorSnowflake;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service
public class RegistrationServiceImpl implements RegistrationService {

    @Autowired
    private SchedulingMapper schedulingMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private PatientMapper patientMapper;

    @Autowired
    private RegistrationMapper registrationMapper;


    /**
     * 1、按条件查询排班表（his_scheduling）里的所有部门编号集合
     * 2、根据部门标号查找部门表（sys_dept）里的部门信息
     */
    @Override
    public AjaxResult listDeptForScheduling(RegistrationQueryDto registrationQueryDto) {
        QueryWrapper<Scheduling> qw = new QueryWrapper<>();
        qw.eq(registrationQueryDto.getDeptId() != null, Scheduling.COL_DEPT_ID,registrationQueryDto.getDeptId());
        qw.eq(StringUtils.isNotBlank(registrationQueryDto.getSchedulingType()), Scheduling.COL_SCHEDULING_TYPE,registrationQueryDto.getSchedulingType());
        qw.eq(StringUtils.isNotBlank(registrationQueryDto.getSubsectionType()), Scheduling.COL_SUBSECTION_TYPE,registrationQueryDto.getSubsectionType());

        String schedulingDay = DateUtil.format(registrationQueryDto.getSchedulingDay(), "yyyy-MM-dd");
        qw.eq(StringUtils.isNotBlank(schedulingDay),Scheduling.COL_SCHEDULING_DAY,schedulingDay);
        qw.select("dept_id");
        List<Scheduling> schedulingList = schedulingMapper.selectList(qw);
        List<Long> deptList = new ArrayList<>();
        for (Scheduling scheduling : schedulingList) {
            deptList.add(scheduling.getDeptId());
        }
        if (CollectionUtil.isNotEmpty(deptList)) {
            return AjaxResult.success(deptMapper.listDeptByDeptIds(deptList));
        } else {
           return AjaxResult.success(Collections.EMPTY_LIST);
        }
    }

    /**
     * 1、根据身份证号查数据库中患者信息，不存在，则新加患者信息；如果存在，则直接获取患者信息
     * 2、如果科室存在，则添加患者挂号信息
     */
    @Override
    public AjaxResult addRegistration(RegistrationFormDto registrationFormDto) {
        RegistrationDto registrationDto = registrationFormDto.getRegistrationDto();
        PatientDto patientDto = registrationFormDto.getPatientDto();
        Patient patient = patientMapper.selectPatientByIdCard(patientDto.getIdCard());
        // 不存在，新加患者信息
        if (ObjectUtils.isEmpty(patient)) {
            Patient newPatient = new Patient();
            BeanUtils.copyProperties(registrationFormDto.getPatientDto(),newPatient);
            String numb = IdGeneratorSnowflake.generatorIdWithProfix(Constants.ID_PROFIX_NO);
            newPatient.setPatientId(numb.substring(0,3)+numb.substring(numb.length()-6));
            newPatient.setCreateTime(new Date());
            newPatient.setSalt(AppMd5Utils.createSalt());
            newPatient.setPassword(AppMd5Utils.md5(newPatient.getPhone().substring(5),newPatient.getSalt(),2));
            patientMapper.insert(newPatient);
            patient = newPatient;
        }
        // 如果挂号的科室不存在（被删除了或停用），则不能挂号
        Dept dept = deptMapper.selectByDeptId(registrationDto.getDeptId());
        if (ObjectUtils.isNotEmpty(dept)) {
            Registration registration = new Registration();
            BeanUtils.copyProperties(registrationDto,registration);
            registration.setPatientName(patient.getName());
            registration.setPatientId(patient.getPatientId());
            registration.setRegId(IdGeneratorSnowflake.generatorIdWithProfix(Constants.ID_PROFIX_GH));
            registration.setRegStatus(Constants.REG_STATUS_0);
            registration.setRegNumber(dept.getRegNumber()+1);
            registration.setCreateBy(registrationDto.getSimpleUser().getUserName());
            registration.setCreateTime(DateUtil.date());
            String visitDate = DateUtil.format(DateUtil.parse(registrationDto.getVisitDate(), "yyyy-MM-dd"), "yyyy-MM-dd");
            registration.setVisitDate(visitDate);
            registrationMapper.insert(registration);
            // 根据部门ID更新号段(挂号编号)
            deptMapper.updateDeptRegNumber(registration.getDeptId(),registration.getRegNumber());
            return AjaxResult.success("",registration.getRegId());
        } else {
            return AjaxResult.fail("请选择挂号的科室");
        }
    }

    /**
     * 挂号单存在 并 未收费状态 才可收费
     */
    @Override
    public AjaxResult collectFee(String registrationId) {
        Registration registration = getRegistration(registrationId);
        if (ObjectUtils.isEmpty(registration)) {
            return AjaxResult.fail("当前挂号单【"+registrationId+"】不存在，请核对后再重新查询");
        }
        if (!registration.getRegStatus().equals(Constants.REG_STATUS_0)) {
            return AjaxResult.fail("当前挂号单【"+registrationId+"】不是未缴费状态，不能缴费");
        }
        registration.setRegStatus(Constants.REG_STATUS_1);
        return AjaxResult.toAjax(registrationMapper.updateById(registration));
    }


    @Override
    public AjaxResult selectRegistrationForPage(RegistrationDto registrationDto) {
        Page<Registration> page = new Page<>(registrationDto.getPageNum(), registrationDto.getPageSize());
        QueryWrapper<Registration> qw = new QueryWrapper<>();
        qw.eq(registrationDto.getDeptId() != null, Registration.COL_DEPT_ID,registrationDto.getDeptId());
        qw.like(StringUtils.isNotBlank(registrationDto.getPatientId()),Registration.COL_PATIENT_ID,registrationDto.getPatientId());
        qw.like(StringUtils.isNotBlank(registrationDto.getRegId()),Registration.COL_REG_ID,registrationDto.getRegId());
        qw.eq(StringUtils.isNotBlank(registrationDto.getSchedulingType()),Registration.COL_SCHEDULING_TYPE,registrationDto.getSchedulingType());
        qw.eq(StringUtils.isNotBlank(registrationDto.getSubsectionType()),Registration.COL_SUBSECTION_TYPE,registrationDto.getSubsectionType());
        qw.eq(StringUtils.isNotBlank(registrationDto.getRegStatus()),Registration.COL_REG_STATUS,registrationDto.getRegStatus());
        qw.eq(StringUtils.isNotBlank(registrationDto.getVisitDate()),Registration.COL_VISIT_DATE,registrationDto.getVisitDate());
        qw.orderByAsc(Registration.COL_CREATE_TIME);
        registrationMapper.selectPage(page,qw);
        return AjaxResult.success("查询成功",page.getRecords(),page.getTotal());
    }

    @Override
    public AjaxResult doInvalid(String registrationId) {
        Registration registration = getRegistration(registrationId);
        if (ObjectUtils.isEmpty(registration)) {
            return AjaxResult.fail("当前挂号单【"+registrationId+"】不存在，作废失败");
        }
        if (!registration.getRegStatus().equals(Constants.REG_STATUS_0)) {
            return AjaxResult.fail("当前挂号单【"+registrationId+"】不是未缴费状态，不能作废");
        }
        registration.setRegStatus(Constants.REG_STATUS_5);
        return AjaxResult.toAjax(registrationMapper.updateById(registration));
    }

    @Override
    public AjaxResult doReturn(String registrationId) {
        Registration registration = getRegistration(registrationId);
        if (ObjectUtils.isEmpty(registration)) {
            return AjaxResult.fail("当前挂号单【"+registrationId+"】不存在，退号失败");
        }
        if (!registration.getRegStatus().equals(Constants.REG_STATUS_1)) {
            return AjaxResult.fail("当前挂号单【"+registrationId+"】不是待就诊状态，不能退号");
        }
        registration.setRegStatus(Constants.REG_STATUS_4);
        return AjaxResult.toAjax(registrationMapper.updateById(registration));
    }

    private Registration getRegistration(String registrationId) {
        QueryWrapper<Registration> qw = new QueryWrapper<>();
        qw.eq(Registration.COL_REG_ID,registrationId);
        return registrationMapper.selectOne(qw);
    }

    /**
     * 根据科室id 查找待就诊的挂号信息
     * 查询待就诊的挂号信息（条件:待就诊，当天，当前时间段(早/下/晚)，门诊/急诊）
     */
    @Override
    public AjaxResult queryRegistration(String schedulingType, Long deptId, String regStatus,String subsectionType) {
        QueryWrapper<Registration> qw = new QueryWrapper<>();
        qw.eq(Registration.COL_DEPT_ID,deptId);
        qw.eq(Registration.COL_REG_STATUS,regStatus);
        if (!regStatus.equals(Constants.REG_STATUS_2)) {
            qw.eq(Registration.COL_VISIT_DATE,DateUtil.today());
        }
        qw.eq(StringUtils.isNotBlank(subsectionType),Registration.COL_SUBSECTION_TYPE,subsectionType);
        qw.eq(Registration.COL_SCHEDULING_TYPE,schedulingType);
        qw.orderByAsc(Registration.COL_REG_NUMBER);
        return AjaxResult.success(registrationMapper.selectList(qw));
    }

}


